//-------------------------------------------------------------------
//	Copyright (c) 2010-2012 Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_RTPASS_MESSAGES_H
#define _UX_RTPASS_MESSAGES_H

#include "IRTPass.h"

namespace Engine
{
namespace RenderUtils
{

	//
	// Render Technique Pass Messages
	//

	struct TRTMessage
	{
		// types
		struct TGetPass
		{
			IRTPass			*		pPass;		// result
			IRTPass::EPassType	eType;
		};

		struct TGetCameras
		{
			TCameraRenderQueue::camera_rq_array_t *	pCameras;	// result
			e_camera::type							eType;
		};

		struct TGetProfilerIdx
		{
			const string *			pName;
			uint		 *			pIndex;		// result
		};

		struct TGetBool
		{
			const string *			pName;
			bool		 *			pBool;
		};

		struct TGetInt
		{
			const string *			pName;
			int32		 *			pInt;
		};

		struct TGetQuery
		{
			CQueryObject *			pQuery;
			gl_query::type			eType;
		};

		struct TGetPasses
		{
			pod_array<IRTPass *> *	pPasses;
			IRTPass				*	pLast;
		};

		enum EMsgType
		{
			// ivec4
			GET_ITERATION	= 0,

			// TGetPass
			GET_PASS,

			// TCameraRenderQueue
			GET_CURRENT_RENDER_QUEUE,

			// TGetCameras
			GET_CAMERAS,

			// FBO_t
			GET_FBO,

			// IPostProcess
			GET_USER_POSTPROCESS,

			// TGetProfilerIdx
			GET_PROFILER_INDEX,

			// TGetBool
			GET_BOOL,

			// TGetInt
			GET_INT,

			// TGetQuery
			GET_QUERY,

			// TGetPasses
			GET_LIGHT_AND_SHADOW_SETUP,

			UNKNOWN			= 0xFFFF,
		};

		enum {
			MAX_ITERATIONS	= 0xFFFFFFFF ^ (1<<31)
		};

		union UMessageData
		{
			ivec4				*	pIVec4;
			TCameraRenderQueue	**	pCameraRQ;
			FBO_t				*	pFBO;
			IPostProcessPtr		*	pPostProcess;
			TGetPass				sPass;
			TGetCameras				sCameras;
			TGetProfilerIdx			sProfiler;
			TGetBool				sBool;
			TGetInt					sInt;
			TGetQuery				sQuery;
			TGetPasses				sPasses;
		};


		// values
		EMsgType	eType;
		UMessageData	sData;
		int				iDepth;


		// methods
		TRTMessage(): eType(UNKNOWN) {}

		void GetIteration(int depth = MAX_ITERATIONS)
		{
			eType				= GET_ITERATION;
			sData.pIVec4		= nullptr;
			iDepth				= depth;
		}

		void GetPass(IRTPass::EPassType type, int depth = MAX_ITERATIONS)
		{
			eType				= GET_PASS;
			sData.sPass.pPass	= nullptr;
			sData.sPass.eType	= type;
			iDepth				= depth;
		}

		void GetCameraRQ(int depth = MAX_ITERATIONS)
		{
			eType				= GET_CURRENT_RENDER_QUEUE;
			iDepth				= depth;
			sData.pCameraRQ		= nullptr;
		}

		void GetCameras(e_camera::type camera_type, int depth = MAX_ITERATIONS)
		{
			eType					= GET_CAMERAS;
			iDepth					= depth;
			sData.sCameras.eType	= camera_type;
			sData.sCameras.pCameras	= nullptr;
		}

		void GetFBO(int depth = MAX_ITERATIONS)
		{
			eType				= GET_FBO;
			iDepth				= depth;
			sData.pFBO			= nullptr;
		}

		void GetUserPostProcess(int depth = MAX_ITERATIONS)
		{
			eType				= GET_USER_POSTPROCESS;
			iDepth				= depth;
			sData.pPostProcess	= nullptr;
		}

		void GetProfilerIndex(const string &sName, int depth = MAX_ITERATIONS)
		{
			eType					= GET_PROFILER_INDEX;
			iDepth					= depth;
			sData.sProfiler.pName	= &sName;
			sData.sProfiler.pIndex	= nullptr;
		}

		void GetBool(const string &sName, int depth = MAX_ITERATIONS)
		{
			eType				= GET_BOOL;
			iDepth				= depth;
			sData.sBool.pBool	= nullptr;
			sData.sBool.pName	= &sName;
		}

		void GetInt(const string &sName, int depth = MAX_ITERATIONS)
		{
			eType				= GET_INT;
			iDepth				= depth;
			sData.sInt.pInt		= nullptr;
			sData.sInt.pName	= &sName;
		}

		void GetQuery(gl_query::type type, int depth = MAX_ITERATIONS)
		{
			eType				= GET_QUERY;
			iDepth				= depth;
			sData.sQuery.eType	= type;
			sData.sQuery.pQuery	= nullptr;
		}

		void GetLightAndShadowSetup(pod_array<IRTPass *> &passes, int depth = MAX_ITERATIONS)
		{
			eType				= GET_LIGHT_AND_SHADOW_SETUP;
			iDepth				= depth;
			sData.sPasses.pLast	= nullptr;
			sData.sPasses.pPasses = & passes;
		}
	};

//-------------------------------------------------------------------

}	// RenderUtils
}	// Engine

#endif	// _UX_RTPASS_MESSAGES_H